package imp

import (
	sqlc "bgs/db/sqlc"
	orderGrpc "bgs/grpc/gen/service/order"
	"bgs/grpc/gen/shared/message"
	"bgs/grpc/imp/enums"
	"bgs/service/model"
	"context"
	"encoding/json"
	"strconv"
)

/****************************************************************************************/
/*                               orderOfB entity of helper                              */
/****************************************************************************************/

func transformOrderItemForBEntityToPb(o sqlc.Order) *orderGrpc.OrderItemForBEntity {
	orderExtInfo := &model.OrderExtInfo{}
	json.Unmarshal(o.ExtInfo, orderExtInfo)

	return &orderGrpc.OrderItemForBEntity{
		Id:                  o.ID,
		Ordered:             sqlc.GoTimeToPBTimestamp(o.Ordered),
		SerialNumber:        o.SerialNumber,
		BrandId:             o.BrandID,
		ActivityId:          o.ActivityID,
		OrderType:           o.OrderType,
		OrderStatus:         o.OrderStatus,
		DeliveryMode:        o.DeliveryMode,
		Amount:              o.Amount,
		IsApplyForAfterSale: o.IsApplyForAfterSale,
		IsInAfterSale:       o.IsInAfterSale,
		OrderDetails:        mapOrderDetailEntityToPb(orderExtInfo.Details, transformOrderDetailEntityToPb),
		BrandName:           orderExtInfo.BrandName,
		BrandPic:            orderExtInfo.BrandPic,
		BrandTel:            orderExtInfo.BrandTel,
		ActivityName:        orderExtInfo.ActivityName,
		ActivityTel:         orderExtInfo.ActivityTel,
		BuyerNickName:       orderExtInfo.BuyerNickName,
		BuyerPic:            orderExtInfo.BuyerPic,
	}
}

func mapOrderItemForBEntityToPb(list []sqlc.Order, f func(sqlc.Order) *orderGrpc.OrderItemForBEntity) []*orderGrpc.OrderItemForBEntity {
	r := make([]*orderGrpc.OrderItemForBEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                               orderOfB entity of query                               */
/****************************************************************************************/

// ListOrderItemsForB 分页获取多个订单(视角B)
func (s *OrderAPIService) ListOrderItemsForB(ctx context.Context, req *orderGrpc.ListOrderItemsForBRequest) (res *orderGrpc.ListOrderItemsForBResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("orderOfB->ListOrderItemsForB:%v", req)

	res = &orderGrpc.ListOrderItemsForBResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}

	q := s.dao.Q
	ts := sqlc.PBTimestampToGoTime(req.Ts)
	brandID := req.BrandId
	isAll := req.IsAll
	orderStatuses := req.OrderStatuses
	searchTerm := req.SearchTerm
	if !(searchTerm == "" || searchTerm == string(enums.SearchTermActivity) || searchTerm == string(enums.SearchTermSpokesman)) {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     "searchTerm不支持",
		}
		return
	}

	var searchValue int64
	if req.SearchValue != "" {
		searchValue, err = strconv.ParseInt(req.SearchValue, 10, 64)
		if err != nil {
			res.OpRet = &message.OperationResult{
				Success: false,
				Code:    400,
				Msg:     err.Error(),
			}
			return
		}
	}

	total, err := q.CountOrdersAsBrandSearcher(ctx, sqlc.CountOrdersAsBrandSearcherParams{
		Created:       ts,
		BrandID:       brandID,
		IsAll:         isAll,
		OrderStatuses: orderStatuses,
		SearchTerm:    searchTerm,
		SearchValue:   searchValue,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}

	if total == 0 {
		// 不用继续调用listfunc
		return
	}

	orders, err := q.ListOrdersAsBrandSearcher(ctx, sqlc.ListOrdersAsBrandSearcherParams{
		Limit:         req.Limit,
		Offset:        req.Offset,
		Created:       ts,
		BrandID:       brandID,
		IsAll:         isAll,
		OrderStatuses: orderStatuses,
		SearchTerm:    searchTerm,
		SearchValue:   searchValue,
	})
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.OrderItemsForB = mapOrderItemForBEntityToPb(orders, transformOrderItemForBEntityToPb)
	return
}